package com.sample.config;

import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import com.swak.boot.config.customizer.SyncDataSourceOptionsCustomizer;
import com.swak.boot.config.jdbc.database.DataSourceProperties;
import com.swak.boot.config.jdbc.database.HikariDataSourceAutoConfiguration;
import com.swak.persistence.datasource.DynamicDataSource;
import com.swak.persistence.datasource.DynamicDataSourceAspect;
import com.swak.utils.Maps;

/**
 * 适合主从模式的多数据源配置
 * 
 * @author lifeng
 */
@Configuration
public class DynamicDSConfig {

	// ************ 主定义主配置的资源配置 ****************
	@ConfigurationProperties(prefix = "spring.datasource.user")
	public static class UserDataSourceProperties extends DataSourceProperties {

	}

	@ConfigurationProperties(prefix = "spring.datasource.goods")
	public static class GoodsDataSourceProperties extends DataSourceProperties {

	}

	@ConfigurationProperties(prefix = "spring.datasource.order")
	public static class OrderDataSourceProperties extends DataSourceProperties {

	}

	@Bean
	public UserDataSourceProperties UserDataSourceProperties() {
		return new UserDataSourceProperties();
	}

	@Bean
	public GoodsDataSourceProperties GoodsDataSourceProperties() {
		return new GoodsDataSourceProperties();
	}

	@Bean
	public OrderDataSourceProperties OrderDataSourceProperties() {
		return new OrderDataSourceProperties();
	}

	@Bean
	@Primary
	public DataSource dynamicDataSource(UserDataSourceProperties userDataSourceProperties,
			GoodsDataSourceProperties goodsDataSourceProperties, OrderDataSourceProperties orderDataSourceProperties,
			ObjectProvider<List<SyncDataSourceOptionsCustomizer>> customizersProvider) {
		/*
		 * 创建数据源
		 */
		DataSource userDataSource = new HikariDataSourceAutoConfiguration("User")
				.hikariDataSource(userDataSourceProperties, customizersProvider);
		DataSource goodsDataSource = new HikariDataSourceAutoConfiguration("Goods")
				.hikariDataSource(goodsDataSourceProperties, customizersProvider);
		DataSource orderDataSource = new HikariDataSourceAutoConfiguration("Order")
				.hikariDataSource(orderDataSourceProperties, customizersProvider);

		// 配置多数据源
		Map<Object, Object> targetDataSources = Maps.newHashMap();
		targetDataSources.put("Order", orderDataSource);
		targetDataSources.put("User", userDataSource);
		targetDataSources.put("Goods", goodsDataSource);

		// 配置动态数据源
		DataSource dynamicDataSource = new DynamicDataSource(orderDataSource, targetDataSources);
		return dynamicDataSource;
	}

	/**
	 * 通过 Aop 来开启自动数据源的切换
	 * 
	 * @return
	 */
	@Bean
	public DynamicDataSourceAspect dynamicDataSourceAspect() {
		return new DynamicDataSourceAspect();
	}
}